package com.zyzd.baseprojectofvolly.base.activity;


import android.support.annotation.NonNull;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.zyzd.baseprojectofvolly.R;
import com.zyzd.baseprojectofvolly.bean.remote.ApiResultBean;
import com.zyzd.baseprojectofvolly.utils.StringUtils;
import com.zyzd.baseprojectofvolly.utils.api.ErrorCodeUtil;
import com.zyzd.baseprojectofvolly.utils.volley.VolleyHelper;
import com.zyzd.commontools.log.TLog;

import java.lang.reflect.Type;
import java.util.Map;


/**
 * Created by 李宗源 on 2016/11/8.
 */

public abstract class BaseNetActivity<T> extends BaseActivity {

    /**
     * get请求
     * <p>
     * 默认使用getClass().getSimpleName()作为tag
     *
     * @param url 请求路径
     */
    protected void requestDataByGet(String url) {
        requestDataByGet(url, getSimpleName());
    }

    /**
     * get请求
     *
     * @param url 请求路径
     * @param tag 请求标志，当页面由多个请求时可以用以区分
     */
    protected void requestDataByGet(String url, final String tag) {
        VolleyHelper.stringRequest(url, tag, getListener(tag), getErrorListener(tag));
    }

    /**
     * post请求
     * <p>
     * 默认使用getClass().getSimpleName()作为tag
     *
     * @param url
     * @param params
     */
    protected void requestDataByPost(String url, Map<String, String> params) {
        requestDataByPost(url, params, getSimpleName());
    }

    /**
     * post请求
     *
     * @param url    请求路径
     * @param tag    请求标志，当页面由多个请求时可以用以区分
     * @param params 请求参数
     */
    protected void requestDataByPost(String url, Map<String, String> params, final String tag) {
        VolleyHelper.stringRequest(url, tag, params, getListener(tag), getErrorListener(tag));
    }

    @NonNull
    private Response.Listener<String> getListener(final String tag) {
        return new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                BaseNetActivity.this.onResponse(response, tag);
            }
        };
    }

    @NonNull
    private Response.ErrorListener getErrorListener(final String tag) {
        return new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                BaseNetActivity.this.onErrorResponse(error, tag);
            }
        };
    }

    /**
     * 成功请求结果
     *
     * @param response
     * @param tag
     */
    protected void onResponse(String response, String tag) {
        if (StringUtils.isEmpty(response)) {
            TLog.d("zyzd", getSimpleName() + ">>onResponse--> " + getString(R.string.requestError_emptyData));
            return;
        }
        onSuccess(response, tag);
    }

    /**
     * 网络请求失败
     *
     * @param error
     * @param tag
     */
    private void onErrorResponse(VolleyError error, String tag) {
        TLog.d("zyzd", getSimpleName() + ">>onErrorResponse--> " + error.getCause() + getString(R.string.requestError_net));
        onRequestFinish(tag);//请求结束回调
        showToast(getString(R.string.requestError_net));
    }


    protected void onSuccess(String response, String tag) {
        TLog.d("zyzd", getSimpleName() + ">>onSuccess-response-> " + response);
        try {
            ApiResultBean resultBean = new Gson().fromJson(response, getType(tag));

            if (resultBean == null) {
                TLog.d("zyzd", getSimpleName() + ">>resultBean--> " + getString(R.string.requestError_emptyData));
                onRequestFail(tag);
                return;
            }

            if (resultBean.getError_no() != ErrorCodeUtil.ERROR_000001) {
                onRequestErrorNo(resultBean.getError_no(), resultBean.getMsg(), tag);
                return;
            }
            if (resultBean.getData() == null) {
                TLog.d("zyzd", getSimpleName() + ">>data--> " + getString(R.string.requestError_emptyData));
                onDataNull(tag);
            } else {
                if (tag.equals(getSimpleName())) {
                    parseData((T) resultBean.getData(), tag);
                } else {
                    parseOtherData(resultBean.getData(), tag);
                }
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            TLog.d("zyzd", getSimpleName() + ">>onSuccses--> " + getString(R.string.requestError_JsonSyntaxException));
            onRequestFail(tag);
        } catch (Exception e) {
            TLog.d("zyzd", getSimpleName() + ">>onSuccess--> otherException：" + e.getMessage());
            onRequestFail(tag);
        } finally {
            onRequestFinish(tag);//请求结束回调
        }
    }

    /**
     * 其他请求的数据解析
     *
     * @param data
     * @param tag
     */
    protected void parseOtherData(Object data, String tag) {

    }

    /**
     * 当返回的有效数据为空时，一半情况视为请求失败，但不排除存在不返回反馈数据的设计，所以保留该方法，以用于重写
     *
     * @param tag
     */
    protected void onDataNull(String tag) {
        onRequestFail(tag);
    }

    /**
     * 解析的数据类型
     *
     * @return
     */
    protected abstract Type getType(String tag);

    /**
     * 解析数据(备注：一般情况下，要保留)
     *
     * @param data
     * @param tag
     */
    protected abstract void parseData(T data, String tag);

    /**
     * 错误信息
     *
     * @param errorNo
     * @param message
     */
    protected void onRequestErrorNo(int errorNo, String message, String tag) {
        TLog.d("zyzd", "BaseNetActivity>>onRequestErrorNo--> errorNo:" + errorNo + "  message:" + message);
        onRequestFail(tag);
        switch (errorNo) {//TODO 后台没有返回对应码，故暂时无效
//            case ERROR_100001:
//            case ERROR_100002:
//                showToast("登录信息过时，请重新登录");
//                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(new Intent(Constant.ACTION_LOGIN_OUT));//关闭当前所有
//                break;
            default:
                onRequestFail(tag);
                break;
        }
    }

    protected void onRequestFinish(String tag) {

    }

    protected void onRequestFail(String tag) {

    }
}
